use actix_web::{web, HttpRequest, HttpResponse};
use attestation_common::log::error;
use endorserment::services::cert_service::{
    AddCertRequest, CertService, DeleteRequest, QueryInfo, UpdateCertRequest,
};
use sea_orm::DatabaseConnection;

use std::sync::Arc;

pub async fn get_certs(
    db: web::Data<Arc<DatabaseConnection>>,
    query: web::Query<QueryInfo>,
) -> HttpResponse {
    let ids =
        query.ids.clone().and_then(
            |ids| match serde_json::from_str::<Vec<String>>(ids.as_str()) {
                Ok(parsed_ids) => Some(parsed_ids),
                Err(e) => {
                    error!("Parsing ids parameters failed {}", e);
                    Some(Vec::new())
                }
            },
        );
    CertService::get_all_certs(db, &ids, &query.cert_type)
        .await
        .unwrap_or_else(|e| {
            error!("Failed to fetch certs: {:?}", e);
            HttpResponse::InternalServerError().body("Failed to fetch certs")
        })
}

pub async fn add_cert(
    db: web::Data<Arc<DatabaseConnection>>,
    add_cert: web::Json<AddCertRequest>,
    req: HttpRequest,
) -> HttpResponse {
    if let Some(user_id) = req.headers().get("user_id") {
        if let Ok(user_id) = user_id.to_str() {
            return CertService::add_cert(db, add_cert, user_id.to_string())
                .await
                .unwrap_or_else(|e| {
                    error!("Failed to add cert: {:?}", e);
                    HttpResponse::InternalServerError().body("Failed to add cert")
                });
        }
    }
    HttpResponse::InternalServerError().body("Failed to add cert")
}

pub async fn delete_cert(
    db: web::Data<Arc<DatabaseConnection>>,
    delete_request: web::Json<DeleteRequest>,
) -> HttpResponse {
    CertService::delete_certs(db, delete_request)
        .await
        .unwrap_or_else(|e| {
            error!("Failed to delete certs: {:?}", e);
            HttpResponse::InternalServerError().body("Failed to delete certs")
        })
}

pub async fn update_cert(
    db: web::Data<Arc<DatabaseConnection>>,
    add_cert: web::Json<UpdateCertRequest>,
    req: HttpRequest,
) -> HttpResponse {
    if let Some(user_id) = req.headers().get("user_id") {
        if let Ok(user_id) = user_id.to_str() {
            return CertService::update_cert(db, add_cert, user_id.to_string())
                .await
                .unwrap_or_else(|e| {
                    error!("Failed to add cert: {:?}", e);
                    HttpResponse::InternalServerError().body("Failed to add cert")
                });
        }
    }
    HttpResponse::InternalServerError().body("Failed to add cert")
}
